package cs.android.rpc;

import java.util.concurrent.atomic.AtomicBoolean;

import static cs.android.lang.AndroidLang.sleep;
import static cs.java.lang.Lang.error;
import static cs.java.lang.Lang.iterate;
import static cs.java.lang.Lang.list;

import android.os.Handler;
import android.os.Looper;
import cs.android.lang.AndroidLang;
import cs.java.collections.List;
import cs.java.lang.Run;

public class RequestManager {

	protected Handler threadHandler;
	private final AtomicBoolean isHandlerReady = new AtomicBoolean(false);
	private final List<Run> waitingRequests = list();

	public RequestManager() {
		new Thread() {
			@Override public void run() {
				startThreadHandler();
			};
		}.start();
	}

	protected Run wrapRunnable(final Runnable request) {
		return new Run() {
			public void run() {
				try {
					request.run();
				} catch (Exception e) {
					error(e);
					AndroidLang.getAplication().logException(e);
				}
			}
		};
	}

	private void startThreadHandler() {
		Looper.prepare();
		threadHandler = new Handler();
		isHandlerReady.set(true);
		sleep(50);
		for (final Run request : iterate(waitingRequests).reverse())
			threadHandler.postAtFrontOfQueue(request);
		Looper.loop();
	}

	public void postAtFrontOfQueue(final Runnable request) {
		threadHandler.postAtFrontOfQueue(wrapRunnable(request));
	}

	public void send(final Run request) {
		if (isHandlerReady.get()) threadHandler.post(wrapRunnable(request));
		else waitingRequests.add(wrapRunnable(request));
	}
}
